﻿namespace ReplayDataFile
{
    using System;
    using System.Collections.Generic;
    using System.Runtime.CompilerServices;

    public class ForwordDataReader : BlockDataBase
    {
        private DateTime beginTime;
        private List<BlockFile> bfList;
        private BlockFileReader bfReader;
        private bool isReadOver;
        private int nextFileIndex;
        private List<int> readDataTypeList;

        public ForwordDataReader(string filePath) : base(filePath)
        {
            this.bfList = new List<BlockFile>();
        }

        public override bool Close()
        {
            if (this.bfReader != null)
            {
                this.bfReader.Close();
                this.bfReader = null;
            }
            return base.Close();
        }

        private List<BlockFile> GetBlockFileList(DateTime beginTime)
        {
            DateTime time;
            DateTime time2;
            List<BlockFile> list = new List<BlockFile>();
            base.GetDataTimeRange(out time, out time2);
            if (beginTime <= time2)
            {
                if (beginTime <= time)
                {
                    list.AddRange(base.FileList);
                    return list;
                }
                bool flag = false;
                foreach (BlockFile file in base.FileList)
                {
                    if (!flag)
                    {
                        file.GetDataTimeRange(out time, out time2);
                        if (beginTime <= time2)
                        {
                            flag = true;
                        }
                    }
                    if (flag)
                    {
                        list.Add(file);
                    }
                }
            }
            return list;
        }

        public long GetPosition()
        {
            if (this.bfReader == null)
            {
                return 0L;
            }
            long num = 0L;
            foreach (BlockFile file in base.FileList)
            {
                if (file.FileName == this.bfReader.FileName)
                {
                    return (num + this.bfReader.GetPosition());
                }
                num += file.Header.RecordCount;
            }
            return num;
        }

        public List<DataRecord> ReadNext(int recCount)
        {
            bool flag;
            List<DataRecord> list = new List<DataRecord>();
            if (base.FileList.Count == 0)
            {
                return list;
            }
            if (this.isReadOver || (this.bfReader == null))
            {
                return list;
            }
            if ((this.bfList == null) || (this.bfList.Count == 0))
            {
                return list;
            }
            List<DataRecord> collection = this.bfReader.ReadNext(recCount);
            if (collection.Count >= recCount)
            {
                list = collection;
                goto Label_0172;
            }
        Label_0169:
            flag = true;
            list.AddRange(collection);
            if (list.Count < recCount)
            {
                if (this.nextFileIndex >= this.bfList.Count)
                {
                    this.isReadOver = true;
                }
                else
                {
                    this.bfReader.Close();
                    BlockFile file = this.bfList[this.nextFileIndex++];
                    this.bfReader = new BlockFileReader(file.FileName);
                    if (this.bfReader.Open())
                    {
                        this.bfReader.SetPosition(DateTime.MinValue);
                        int count = recCount - collection.Count;
                        collection = this.bfReader.ReadNext(count);
                        goto Label_0169;
                    }
                    this.isReadOver = true;
                }
            }
        Label_0172:
            this.ReadRecordTotalCount += list.Count;
            return list;
        }

        public void SetPosition(DateTime time)
        {
            this.SetPosition(0L, time, null);
        }

        public void SetPosition(long recNo)
        {
            this.SetPosition(recNo, (List<int>) null);
        }

        public void SetPosition(DateTime time, List<int> dataTypeList)
        {
            this.SetPosition(0L, time, dataTypeList);
        }

        public void SetPosition(long recNo, List<int> dataTypeList)
        {
            if (this.bfReader != null)
            {
                this.bfReader.Close();
            }
            if (dataTypeList != null)
            {
                this.readDataTypeList = new List<int>();
                this.readDataTypeList.AddRange(dataTypeList);
            }
            else
            {
                this.readDataTypeList = null;
            }
            this.ReadRecordTotalCount = 0L;
            this.nextFileIndex = 0;
            this.isReadOver = false;
            for (int i = 0; i < base.FileList.Count; i++)
            {
                BlockFile file = base.FileList[i];
                long firstRecordNo = file.Header.FirstRecordNo;
                long num3 = firstRecordNo + file.Header.RecordCount;
                if ((recNo >= firstRecordNo) && (recNo < num3))
                {
                    this.bfReader = new BlockFileReader(file.FileName);
                    if (this.bfReader.Open())
                    {
                        this.bfReader.SetPosition(recNo, dataTypeList);
                        this.nextFileIndex = i + 1;
                        this.bfList.Clear();
                        for (int j = i; j < base.FileList.Count; j++)
                        {
                            this.bfList.Add(base.FileList[j]);
                        }
                    }
                    else
                    {
                        this.bfReader = null;
                    }
                    break;
                }
            }
        }

        public void SetPosition(long minRecNo, DateTime time)
        {
            this.SetPosition(minRecNo, time, null);
        }

        public void SetPosition(long minRecNo, DateTime time, List<int> dataTypeList)
        {
            if (this.bfReader != null)
            {
                this.bfReader.Close();
            }
            this.beginTime = time;
            if (dataTypeList != null)
            {
                this.readDataTypeList = new List<int>();
                this.readDataTypeList.AddRange(dataTypeList);
            }
            else
            {
                this.readDataTypeList = null;
            }
            this.ReadRecordTotalCount = 0L;
            this.nextFileIndex = 0;
            this.isReadOver = false;
            this.bfList = this.GetBlockFileList(time);
            if (this.bfList.Count > 0)
            {
                BlockFile file = this.bfList[0];
                this.bfReader = new BlockFileReader(file.FileName);
                if (this.bfReader.Open())
                {
                    this.bfReader.SetPosition(minRecNo, time, dataTypeList);
                    this.nextFileIndex++;
                }
                else
                {
                    this.bfReader = null;
                }
            }
        }

        public bool IsReadOver
        {
            get
            {
                return this.isReadOver;
            }
        }

        public long ReadRecordTotalCount { get; private set; }
    }
}

